home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-10-17 | 14.8 KB | 808 lines | [TEXT/MPS ] |
- {
- HideMenuBarExample.p
- MPW 3.0 Pascal source for menu bar hiding example.
- Copyright © 1989 D. Grant Leeper.
- All rights reserved.
- Publication rights granted to MacTutor.
- }
-
- PROGRAM HideMenuBarExample;
-
- USES
- Types, Resources, QuickDraw, Fonts, Events,
- Controls, Windows, Menus, TextEdit, Dialogs,
- ToolUtils, OSUtils, SegLoad, Files, Packages,
- Desk, DiskInit, Memory, OSEvents,
- Traps, ShowHideMBar;
-
- CONST
- kSysEnvironsVersion = 1;
-
- kMinHeap = 7 * 1024;
- kMinSpace = 2 * 1024;
-
- kMinDocH = 424;
- kMinDocV = 70;
-
- kScrollBarAdjust = 15;
-
- kExtremeNeg = -32768;
- kExtremePos = 32767 - 1;
-
- rWindow = 128;
- rMenuBar = 128;
- rAboutAlert = 128;
- rFatalAlert = 129;
-
- rMessages = 128;
- iSelectApp = 1;
- iSelectWind = 2;
- iAltSelectWind = 3;
- iCommandSpace = 4;
- iAltCommandSpace = 5;
- iClick = 6;
- iCommandClick = 7;
-
- mApple = 128;
- iAbout = 1;
-
- mFile = 129;
- iClose = 1;
- iQuit = 2;
-
- mEdit = 130;
- iUndo = 1;
- iCut = 3;
- iCopy = 4;
- iPaste = 5;
- iClear = 6;
-
- VAR
- gMac: SysEnvRec;
- gHasWaitNextEvent: BOOLEAN;
- gInBackground: BOOLEAN;
- { This keeps track of when we need to
- adjust the menus }
- gDirtyMenus: BOOLEAN;
- { gHasMenuBar saves the visibility of the
- menu bar while we're in the background. }
- gHasMenuBar: BOOLEAN;
- { Create these once rather than each time
- through the event loop. }
- gOutsideRgn: RgnHandle;
- gInsideRgn: RgnHandle;
-
- {$S Main}
- FUNCTION IsDAWindow(window: WindowPtr): BOOLEAN;
-
- BEGIN
- IsDAWindow :=
- (window <> NIL) &
- (WindowPeek(window)^.windowKind < 0)
- END; { IsDAWindow }
-
- {$S Main}
- FUNCTION IsAppWindow(window: WindowPtr): BOOLEAN;
-
- BEGIN
- IsAppWindow :=
- (window <> NIL) &
- (WindowPeek(window)^.windowKind =
- userKind)
- END; { IsAppWindow }
-
- {$S Main}
- PROCEDURE DoToAllAppWindows(
- PROCEDURE DoThis(window: WindowPtr));
-
- VAR
- window: WindowPeek;
-
- BEGIN
- window := WindowPeek(FrontWindow);
- WHILE window <> NIL DO
- BEGIN
- IF window^.windowKind = userKind THEN
- DoThis(WindowPtr(window));
- window := window^.nextWindow
- END { WHILE }
- END; { DoToAllAppWindows }
-
- {$S Main}
- PROCEDURE FatalError;
-
- VAR
- itemHit: INTEGER;
-
- BEGIN
- SetCursor(arrow);
- itemHit := CautionAlert(rFatalAlert, NIL);
- { Be sure the menu bar is visible at exit
- time, but check first for the 128K ROM
- since we may have been called because
- it's not available. }
- IF gMac.machineType >= 0 THEN
- ShowMenuBar;
- ExitToShell
- END; { FatalError }
-
- {$S Main}
- FUNCTION DoCloseWindow(window: WindowPtr): BOOLEAN;
-
- BEGIN
- DoCloseWindow := TRUE;
- IF IsAppWindow(window) THEN
- BEGIN
- CloseWindow(window);
- DisposPtr(Ptr(window))
- END { IF }
- ELSE IF IsDAWindow(window) THEN
- CloseDeskAcc(WindowPeek(window)^.windowKind)
- END; { DoCloseWindow }
-
- {$S Initialize}
- PROCEDURE BringAppToFront;
-
- VAR
- count: INTEGER;
- event: EventRecord;
-
- BEGIN
- FOR count := 1 TO 3 DO
- IF EventAvail(everyEvent, event) THEN
- ; { Ignore it }
- END; { BringAppToFront }
-
- {$S Initialize}
- PROCEDURE Initialize;
-
- VAR
- bIgnore: BOOLEAN;
- event: EventRecord;
- ignore: OSErr;
- total: LONGINT;
- contig: LONGINT;
- storage: Ptr;
- window: WindowPtr;
- menuBar: Handle;
-
- BEGIN
- InitGraf(@thePort);
- InitFonts;
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(NIL);
- InitCursor;
-
- BringAppToFront;
-
- { SysEnvirons must be called before calling
- FatalError. }
- ignore := SysEnvirons(kSysEnvironsVersion,
- gMac);
-
- { Need 128K ROMS to change menu bar height. }
- IF gMac.machineType < 0 THEN
- FatalError;
-
- { The menu bar can be hidden now if desired. }
- HideMenuBar;
-
- IF ORD(GetApplLimit) - ORD(ApplicZone) <
- kMinHeap THEN
- FatalError;
-
- PurgeSpace(total, contig);
- IF total < kMinSpace THEN
- FatalError;
-
- gHasWaitNextEvent :=
- GetTrapAddress(_Unimplemented) <>
- NGetTrapAddress(_WaitNextEvent, ToolTrap);
-
- gInBackground := FALSE;
-
- storage := NewPtr(SizeOf(WindowRecord));
- IF storage = NIL THEN
- FatalError;
- IF gMac.hasColorQD THEN
- window := GetNewCWindow(rWindow, storage,
- Pointer(-1))
- ELSE
- window := GetNewWindow(rWindow, storage,
- Pointer(-1));
- IF window = NIL THEN
- FatalError;
-
- menuBar := GetNewMBar(rMenuBar);
- IF menuBar = NIL THEN
- FatalError;
- SetMenuBar(menuBar);
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR');
- DrawMenuBar;
- gDirtyMenus := TRUE;
-
- gOutsideRgn := NewRgn;
- gInsideRgn := NewRgn
- END; { Initialize }
-
- {$S Main}
- PROCEDURE Terminate;
-
- VAR
- window: WindowPtr;
-
- BEGIN
- window := FrontWindow;
- WHILE window <> NIL DO
- IF DoCloseWindow(window) THEN
- window := FrontWindow
- ELSE
- Exit(Terminate);
- { Must restore menu bar
- before quitting }
- ShowMenuBar;
- ExitToShell
- END; { Terminate }
-
- {$S Main}
- PROCEDURE AdjustMenus;
-
- VAR
- window: WindowPtr;
- appWind: BOOLEAN;
- daWind: BOOLEAN;
- redraw: BOOLEAN;
- menu: MenuHandle;
- wasEnabled: BOOLEAN;
-
- BEGIN
- window := FrontWindow;
- appWind := IsAppWindow(window);
- daWind := IsDAWindow(window);
- redraw := FALSE;
-
- menu := GetMHandle(mFile);
- IF daWind THEN
- EnableItem(menu, iClose)
- ELSE
- DisableItem(menu, iClose);
-
- menu := GetMHandle(mEdit);
- wasEnabled := Odd(menu^^.enableFlags);
- IF daWind THEN
- BEGIN
- EnableItem(menu, 0);
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iPaste);
- EnableItem(menu, iClear)
- END { IF }
- ELSE
- BEGIN
- DisableItem(menu, 0);
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste)
- END; { ELSE }
- IF Odd(menu^^.enableFlags) <> wasEnabled THEN
- redraw := TRUE;
-
- IF redraw THEN
- DrawMenuBar
- END; { AdjustMenus }
-
- {$S Main}
- PROCEDURE DoMenuCommand(menuResult: LONGINT);
-
- VAR
- menu: INTEGER;
- item: INTEGER;
- ignore: INTEGER;
- name: Str255;
- window: WindowPtr;
- bIgnore: BOOLEAN;
-
- BEGIN
- menu := HiWrd(menuResult);
- item := LoWrd(menuResult);
- CASE menu OF
-
- mApple:
- CASE item OF
-
- iAbout:
- ignore := Alert(rAboutAlert,
- NIL);
-
- OTHERWISE
- BEGIN
- GetItem(GetMHandle(mApple),
- item, name);
- ignore := OpenDeskAcc(name);
- gDirtyMenus := TRUE
- END { OTHERWISE }
-
- END; { CASE }
-
- mFile:
- CASE item OF
-
- iClose:
- BEGIN
- window := FrontWindow;
- IF IsDAWindow(window) THEN
- CloseDeskAcc(
- WindowPeek(window)^.
- windowKind);
- gDirtyMenus := TRUE
- END; { iClose }
-
- iQuit:
- Terminate
-
- END; { CASE }
-
- mEdit:
- bIgnore := SystemEdit(item - 1)
-
- END; { CASE }
-
- HiliteMenu(0)
- END; { DoMenuCommand }
-
- {$S Main}
- PROCEDURE DrawWindow(window: WindowPtr);
-
- VAR
- str: Str255;
-
- BEGIN
- SetPort(window);
- EraseRect(window^.portRect);
- DrawGrowIcon(window);
-
- { We display different messages here
- depending on our foreground/background
- and activate/inactivate states. }
-
- IF gInBackground THEN
- BEGIN
- GetIndString(str, rMessages,
- iSelectApp);
- MoveTo(10, 32);
- DrawString(str)
- END { IF }
-
- ELSE IF window <> FrontWindow THEN
- BEGIN
- IF MenuBarVisible THEN
- GetIndString(str, rMessages,
- iSelectWind)
- ELSE
- GetIndString(str, rMessages,
- iAltSelectWind);
- MoveTo(10, 32);
- DrawString(str)
- END { ELSE IF }
-
- ELSE
- IF MenuBarVisible THEN
- BEGIN
- MoveTo(10, 32);
- GetIndString(str, rMessages,
- iCommandSpace);
- DrawString(str)
- END { IF }
- ELSE
- BEGIN
- MoveTo(10, 16);
- GetIndString(str, rMessages,
- iAltCommandSpace);
- DrawString(str);
- MoveTo(10, 32);
- GetIndString(str, rMessages,
- iClick);
- DrawString(str);
- MoveTo(10, 48);
- GetIndString(str, rMessages,
- iCommandClick);
- DrawString(str)
- END { ELSE }
- END; { DrawWindow }
-
- {$S Main}
- PROCEDURE InvalContentRgn(window: WindowPtr);
-
- VAR
- r: Rect;
-
- BEGIN
- SetPort(window);
- r := window^.portRect;
- r.bottom := r.bottom - kScrollBarAdjust;
- r.right := r.right - kScrollBarAdjust;
- InvalRect(r)
- END; { InvalContentRgn }
-
- {$S Main}
- PROCEDURE InvalAppWindContents;
- { Since our window may be behind some DA windows
- we must check all the windows in our layer. }
-
- BEGIN
- DoToAllAppWindows(InvalContentRgn)
- END; { InvalAppWindContents }
-
- {$S Main}
- PROCEDURE InvalGrowRgn(window: WindowPtr);
-
- VAR
- r: Rect;
-
- BEGIN
- SetPort(window);
- r := window^.portRect;
- r.top := r.bottom - kScrollBarAdjust;
- InvalRect(r);
- r := window^.portRect;
- r.left := r.right - kScrollBarAdjust;
- InvalRect(r)
- END; { InvalGrowRgn }
-
- {$S Main}
- PROCEDURE DoGrowWindow(window: WindowPtr;
- event: EventRecord);
-
- VAR
- tempRect: Rect;
- growResult: LONGINT;
-
- BEGIN
- WITH screenBits.bounds DO
- SetRect(tempRect, kMinDocH, kMinDocV,
- right, bottom);
- growResult := GrowWindow(window, event.where,
- tempRect);
- IF growResult <> 0 THEN
- BEGIN
- InvalGrowRgn(window);
- SizeWindow(window, LoWrd(growResult),
- HiWrd(growResult), TRUE);
- InvalGrowRgn(window)
- END { IF }
- END; { DoGrowWindow }
-
- {$S Main}
- PROCEDURE DoZoomWindow(window: WindowPtr;
- part: INTEGER);
-
- BEGIN
- SetPort(window);
- EraseRect(window^.portRect);
- ZoomWindow(window, part, FALSE)
- END; { DoZoomWindow }
-
- {$S Main}
- PROCEDURE DoUpdate(window: WindowPtr);
-
- BEGIN
- IF IsAppWindow(window) THEN
- BEGIN
- BeginUpdate(window);
- IF NOT EmptyRgn(window^.visRgn) THEN
- DrawWindow(window);
- EndUpdate(window)
- END { IF }
- END; { DoUpdate }
-
- {$S Main}
- PROCEDURE DoActivate(window: WindowPtr;
- becomingActive: BOOLEAN);
-
- BEGIN
- IF IsAppWindow(window) THEN
- BEGIN
- { Message to user changes when
- activated or deactivated. }
- InvalContentRgn(window);
- DrawGrowIcon(window);
- gDirtyMenus := TRUE
- END { IF }
- END; { DoActivate }
-
- {$S Main}
- PROCEDURE DoDisk(message: LONGINT);
-
- CONST
- kDILeft = 70;
- kDITop = 50;
-
- VAR
- where: Point;
-
- BEGIN
- IF HiWrd(message) <> noErr THEN
- BEGIN
- SetPt(where, kDILeft, kDITop);
- IF DIBadMount(where, message) = 0 THEN
- { Ignore it }
- END { IF }
- END; { DoDisk }
-
- {$S Main}
- PROCEDURE DoSuspendResume(suspend: BOOLEAN);
-
- BEGIN
- gInBackground := suspend;
-
- IF suspend THEN
- { Save menu bars visibility for when we resume
- then force the menu bar to be displayed. }
- BEGIN
- gHasMenuBar := MenuBarVisible;
- ShowMenuBar
- END { IF }
-
- ELSE IF NOT gHasMenuBar THEN
- { Resuming, hide the menu bar if it was
- hidden prior to our suspension. }
- HideMenuBar;
-
- DoActivate(FrontWindow, NOT suspend);
-
- { Change message to user when
- suspended or resumed. }
- InvalAppWindContents
- END; { DoSuspendResume }
-
- {$S Main}
- PROCEDURE AdjustCursor(mouse: Point;
- cursorRgn: RgnHandle);
-
- VAR
- window: WindowPtr;
- insideRect: Rect;
-
- BEGIN
- window := FrontWindow;
- IF NOT gInBackground &
- NOT IsDAWindow(window) THEN
- BEGIN
- SetRectRgn(gOutsideRgn,
- kExtremeNeg, kExtremeNeg,
- kExtremePos, kExtremePos);
-
- IF IsAppWindow(window) THEN
- BEGIN
- insideRect := window^.portRect;
- insideRect.bottom :=
- insideRect.bottom -
- kScrollBarAdjust;
- insideRect.right :=
- insideRect.right -
- kScrollBarAdjust;
- SetPort(window);
- LocalToGlobal(insideRect.topLeft);
- LocalToGlobal(insideRect.botRight);
- RectRgn(gInsideRgn, insideRect)
- END; { IF }
-
- DiffRgn(gOutsideRgn, gInsideRgn,
- gOutsideRgn);
-
- IF PtInRgn(mouse, gInsideRgn) THEN
- BEGIN
- SetCursor(GetCursor(plusCursor)^^);
- CopyRgn(gInsideRgn, cursorRgn)
- END { IF }
- ELSE
- BEGIN
- SetCursor(arrow);
- CopyRgn(gOutsideRgn, cursorRgn)
- END; { ELSE }
-
- SetEmptyRgn(gOutsideRgn);
- SetEmptyRgn(gInsideRgn)
- END { IF }
- END; { AdjustCursor }
-
- {$S Main}
- PROCEDURE DoEvent(event: EventRecord);
-
- CONST
- kOSEvent = app4Evt;
- kSuspendResumeMessage = 1;
- kResumeMask = 1;
-
- VAR
- part: INTEGER;
- window: WindowPtr;
- key: CHAR;
-
- BEGIN
- CASE event.what OF
-
- mouseDown:
- BEGIN
- part := FindWindow(event.where,
- window);
-
- CASE part OF
-
- inDesk:
- IF PtInMenuBar(
- event.where) THEN
- { User clicked in hidden
- menu bar. Lets show
- off some tricks. }
- BEGIN
- { Show menu bar first if
- command key pressed,
- else just show menus
- without the bar. }
- IF BAnd(event.modifiers,
- cmdKey) <> 0 THEN
- ShowMenuBar;
- DoMenuCommand(
- HiddenMenuSelect(
- event.where));
- { If we showed the menu
- bar here we must be
- sure HiliteMenu(0) is
- called before we hide
- it again. In our case
- DoMenuCommand calls it
- for us. }
- IF BAnd(event.modifiers,
- cmdKey) <> 0 THEN
- HideMenuBar
- END; { IF }
-
- inMenuBar:
- DoMenuCommand(
- MenuSelect(event.where));
-
- inSysWindow:
- SystemClick(event, window);
-
- inContent:
- IF window <> FrontWindow THEN
- SelectWindow(window);
-
- inDrag:
- DragWindow(window,
- event.where,
- screenBits.bounds);
-
- inGrow:
- DoGrowWindow(window, event);
-
- inZoomIn, inZoomOut:
- IF TrackBox(window,
- event.where,
- part) THEN
- DoZoomWindow(window,
- part)
- END { CASE }
- END; { mouseDown }
-
- keyDown, autoKey:
- BEGIN
- key := Chr(BAnd(event.message,
- charCodeMask));
- IF BAnd(event.modifiers,
- cmdKey) <> 0 THEN
- IF event.what = keyDown THEN
- IF key = ' ' THEN
- { User typed
- command-space so
- toggle the menu bar. }
- BEGIN
- IF MenuBarVisible THEN
- HideMenuBar
- ELSE
- ShowMenuBar;
- { Change message to user
- when menu is hidden
- or made visible. }
- InvalAppWindContents
- END { IF }
- ELSE
- DoMenuCommand(
- MenuKey(key))
- END; { keyDown, autoKey }
-
- activateEvt:
- DoActivate(WindowPtr(event.message),
- BAnd(event.modifiers,
- activeFlag) <> 0);
-
- updateEvt:
- DoUpdate(WindowPtr(event.message));
-
- diskEvt:
- DoDisk(event.message);
-
- kOSEvent:
- CASE BAnd(BRotL(event.message, 8),
- $FF) OF
-
- kSuspendResumeMessage:
- DoSuspendResume(
- BAnd(event.message,
- kResumeMask) = 0)
-
- END { CASE }
- END { CASE }
- END; { DoEvent }
-
- {$S Main}
- FUNCTION GlobalMouse: Point;
-
- CONST
- kNoEvents = 0;
-
- VAR
- ignore: BOOLEAN;
- event: EventRecord;
-
- BEGIN
- ignore := OSEventAvail(kNoEvents, event);
- GlobalMouse := event.where
- END; { GlobalMouse }
-
- {$S Main}
- PROCEDURE EventLoop;
-
- VAR
- cursorRgn: RgnHandle;
- gotEvent: BOOLEAN;
- event: EventRecord;
-
- BEGIN
- cursorRgn := NewRgn;
- WHILE TRUE DO
- BEGIN
- IF gDirtyMenus THEN
- BEGIN
- AdjustMenus;
- gDirtyMenus := FALSE
- END; { IF }
-
- AdjustCursor(GlobalMouse, cursorRgn);
-
- IF gHasWaitNextEvent THEN
- gotEvent :=
- WaitNextEvent(everyEvent,
- event, 30,
- cursorRgn)
- ELSE
- BEGIN
- SystemTask;
- gotEvent := GetNextEvent(everyEvent,
- event)
- END; { ELSE }
-
- IF gotEvent THEN
- AdjustCursor(event.where, cursorRgn);
-
- DoEvent(event)
- END { WHILE }
- END; { EventLoop }
-
- PROCEDURE _DataInit; EXTERNAL;
-
- BEGIN
- UnloadSeg(@_DataInit);
- MaxApplZone;
- Initialize;
- UnloadSeg(@Initialize);
- EventLoop
- END. { HideMenuBarExample }
-